﻿namespace Patterns4Net.Tests.Core
{
    using System.Collections.Generic;
    using NUnit.Framework;
    using Patterns4Net.Core;

    [TestFixture]
    public class ArgumentsParserTest
    {
        [Test]
        public void Parse_With_Just_Arguments_Does_Not_Add_Any_Error()
        {
            var arguments = new List<string>();
            var errors = new List<string>();
            var args = new[] { "arg1", "arg2" };
            ArgumentsParser.Parse<DataClass>(args, arguments, errors);

            CollectionAssert.IsEmpty(errors);
            CollectionAssert.AreEquivalent(args, arguments);
        }

        [Test]
        public void Parse_Populates_Name_Property_When_There_Is_Name_Option()
        {
            var arguments = new List<string>();
            var errors = new List<string>();
            var args = new[] { "-name", "test" };
            var result = ArgumentsParser.Parse<DataClass>(args, arguments, errors);

            Assert.AreEqual("test", result.Name);
        }

        [Test]
        public void Parse_Populates_Name_Property_When_There_Is_Name_Option_Finds_Other_Arguments()
        {
            var arguments = new List<string>();
            var errors = new List<string>();
            var args = new[] { "arg1", "-name", "test", "arg2" };
            var result = ArgumentsParser.Parse<DataClass>(args, arguments, errors);

            Assert.AreEqual("test", result.Name);
            CollectionAssert.AreEquivalent(new[] { "arg1", "arg2" }, arguments);
        }

        [Test]
        public void Parse_Sets_Bool_Property_To_True_When_There_Is_Option_Of_The_Same_Name()
        {
            var arguments = new List<string>();
            var errors = new List<string>();
            var args = new[] { "arg1", "-option", "arg2" };
            var result = ArgumentsParser.Parse<ClassWithBool>(args, arguments, errors);

            Assert.IsTrue(result.Option);
            CollectionAssert.AreEquivalent(new[] { "arg1", "arg2" }, arguments);
        }

        [Test]
        public void Parse_Does_Not_Set_Bool_Property_When_There_Is_No_Option_Of_The_Same_Name()
        {
            var arguments = new List<string>();
            var errors = new List<string>();
            var args = new[] { "arg1", "arg2" };
            var result = ArgumentsParser.Parse<ClassWithBool>(args, arguments, errors);

            Assert.IsFalse(result.Option);
            CollectionAssert.AreEquivalent(new[] { "arg1", "arg2" }, arguments);
        }

        public class ClassWithBool
        {
            public ClassWithBool()
            {
                this.Option = false;
            }

            public bool Option { get; set; }
        }

        public class DataClass
        {
            public string Name { get; set; }

            public string Output { get; set; }
        }
    }
}
